package kuberneteshelper

import (
	"context"
	"fmt"
	"io/ioutil"
	"strings"
	"testing"

	"v8s/logger"

	"v8s-controller/internal"
	"v8s-controller/internal/k8s"

	"github.com/stretchr/testify/assert"

	"go.uber.org/zap"

	"k8s.io/client-go/kubernetes"
)

type (
	KubernetesHelper struct {
		client     *kubernetes.Clientset
		repository *k8s.Repository

		log *zap.SugaredLogger
	}
)

func CreateKubernetesHelper(
	client *kubernetes.Clientset,
	repository *k8s.Repository,
) *KubernetesHelper {
	return &KubernetesHelper{
		client:     client,
		repository: repository,
		log:        logger.Logger().Named("kubernetes-helper").Sugar(),
	}
}

func (h *KubernetesHelper) AssertResources(t *testing.T, file string) {
	t.Helper()

	expected, err := ioutil.ReadFile(file)
	if err != nil {
		panic(fmt.Errorf("failed to read file '%s': %s", file, err))
	}

	resources := collectResources(context.Background(), h.client)

	actual := resources.String()
	equal := assert.Equal(t, strings.TrimSpace(string(expected)), strings.TrimSpace(actual))
	if !equal {
		fmt.Println(string(expected))
		fmt.Printf("\nbut was:\n")
		fmt.Println(actual)
	}
}

func (h *KubernetesHelper) InsertData(file string) {
	bytes, err := ioutil.ReadFile(file)
	if err != nil {
		panic(fmt.Errorf("failed to read file '%s': %w", file, err))
	}

	createResources(h.repository, bytes)
}

func (h *KubernetesHelper) Clear(ctx context.Context) {
	namespaces := getUserNamespaces(ctx, h.client)

	for _, namespace := range namespaces {
		err := k8s.DeleteNamespace(ctx, h.client, internal.Namespace(namespace.GetName()))
		if err != nil {
			panic(fmt.Errorf("failed to delete namespace '%s': %w", namespace, err))
		}
	}
}
